
package me.zhengjie.service.impl;

import me.zhengjie.domain.AppArea;
import me.zhengjie.base.TreeNodes;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.service.dto.PlistDto;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.repository.AppAreaRepository;
import me.zhengjie.service.AppAreaService;
import me.zhengjie.service.dto.AppAreaDto;
import me.zhengjie.service.dto.AppAreaQueryCriteria;
import me.zhengjie.service.mapstruct.AppAreaMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author IQW
* @date 2022-07-13
**/
@Service
@RequiredArgsConstructor
public class AppAreaServiceImpl implements AppAreaService {

    private final AppAreaRepository appAreaRepository;
    private final AppAreaMapper appAreaMapper;

    private final UserService userService;
    private final RoleService roleService;

    @Override
    public Map<String,Object> queryAll(AppAreaQueryCriteria criteria, Pageable pageable){

        //获取最小权限
        Integer currentLevel =  Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
        System.out.println("min level:"+currentLevel);
        if(currentLevel<=2){
            //管理员查看所有
        }else{
            //查看当前责任区
            Long userId = SecurityUtils.getCurrentUserId();
            UserDto user = userService.findById(userId);
            criteria.setAreaId(user.getAreaId());
        }

        Page<AppArea> page = appAreaRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(appAreaMapper::toDto));
    }

    @Override
    public List<AppAreaDto> queryAll(AppAreaQueryCriteria criteria){
        return appAreaMapper.toDto(appAreaRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public AppAreaDto findById(Integer areaId) {
        AppArea appArea = appAreaRepository.findById(areaId).orElseGet(AppArea::new);
        ValidationUtil.isNull(appArea.getAreaId(),"AppArea","areaId",areaId);
        return appAreaMapper.toDto(appArea);
    }

    @Override
    public AppAreaDto info(Integer areaId,String name) {

        AppArea appArea = null;
        //先忽略areaId
        if(StringUtils.isEmpty(name)){
            //查询该用户所在责任区
            UserDto userDto = userService.findById(SecurityUtils.getCurrentUserId());
            areaId = userDto.getAreaId();
            appArea = appAreaRepository.findById(areaId).orElseGet(AppArea::new);

        }else{
            List<AppArea> appAreas = appAreaRepository.findByTitle(name);
            if(appAreas.size() > 0){
                appArea = appAreas.get(0);
            }
        }

        AppAreaDto areaDto = appAreaMapper.toDto(appArea);
        if(null != areaDto) {
            //查询父级名称
            if (areaDto.getFid() == 0){
                areaDto.setSname("");
            }else{
                AppArea appAreaF = appAreaRepository.findById(areaDto.getFid()).orElseGet(AppArea::new);
                areaDto.setSname(appAreaF.getTitle());
            }
            //查询是否有下级
            List<AppArea> appAreaSons = appAreaRepository.findByFid(areaDto.getAreaId());
            if(appAreaSons.size() == 0){
                areaDto.setClick(0);
            }else{
                areaDto.setClick(1);
            }
        }
        return areaDto;
    }

    @Override
    public List plist(Integer areaId,String name,String keyword) {

        AppArea appArea = null;
        //先忽略areaId
        if(StringUtils.isEmpty(name)){
            //查询该用户所在责任区
            UserDto userDto = userService.findById(SecurityUtils.getCurrentUserId());
            areaId = userDto.getAreaId();
            appArea = appAreaRepository.findById(areaId).orElseGet(AppArea::new);

        }else{
            List<AppArea> appAreas = appAreaRepository.findByTitle(name);
            if(appAreas.size() > 0){
                appArea = appAreas.get(0);
                areaId = appArea.getAreaId();
            }
        }
        //根据areaId查询出所有人员
//        List<User> list = userService.findByAreaId2(areaId);
        List<UserDto> list = userService.queryAll3(areaId,keyword);

        List<PlistDto> lists = new ArrayList<>();
        for (UserDto item :list){
            lists.add(new PlistDto(item.getNickName(),"巡护员",appArea.getTitle()));
        }
        return  lists;
    }

    @Override
    public List<AppArea> findByFid(Integer fid) {
        return appAreaRepository.findByFid(fid);
    }

    @Override
    public List<Integer>  getChildrenIds(List<AppArea> lists) {
        List<Integer> list = new ArrayList<>();
        lists.forEach(dept -> {
                    if (dept!=null && dept.getStatus()==1) {
                        List<AppArea> depts = appAreaRepository.findByFid(dept.getAreaId());
                        if (depts.size() != 0) {
                            list.addAll(getChildrenIds(depts));
                        }
                        list.add(dept.getAreaId());
                    }
                }
        );
        return list;
    }

    @Override
    public List<TreeNodes> getChildrenList(AppAreaQueryCriteria criteria) {

        List<AppArea> listAll = appAreaRepository.findAll();
        List<TreeNodes> org = new ArrayList<>();
        for (AppArea appArea : listAll){
            TreeNodes treeNodes = new TreeNodes(appArea.getAreaId(),appArea.getFid(),1,appArea.getTitle());
            org.add(treeNodes);
        }
        return  TreeUtils.buildTrees(org);
    }

    @Override
    public List<TreeNodes> getChildrenUserList(AppAreaQueryCriteria criteria) {

        List<AppArea> listAll = appAreaRepository.findAll();
        List<TreeNodes> org = new ArrayList<>();
        for (AppArea appArea : listAll){
            //设置组不可选
            TreeNodes treeNodes = new TreeNodes(appArea.getAreaId(),appArea.getFid(),0,appArea.getTitle(),true);
            org.add(treeNodes);
        }
        List<TreeNodes> rets =  TreeUtils.buildTrees(org);
        for (TreeNodes nodes : rets){

            for(TreeNodes nodes2 : nodes.getChildren()){
                for(TreeNodes nodes3 : nodes2.getChildren()){
                    //三级加人
                    this.addUsers(criteria,nodes3);
                }
                //二级加人
                this.addUsers(criteria,nodes2);
            }
            //一级加人
            this.addUsers(criteria,nodes);
        }
        return rets;

    }

    //在节点同级别，添加人员
    private void addUsers(AppAreaQueryCriteria criteria,TreeNodes nodes){
        List<User> users ;
        //0表示查询所有人，1表示按当前会员级别过滤人员
        int flag = 0;
        if(null != criteria.getFid() && criteria.getFid() == 1) {
//                flag = 1;  //先全部显示，不搞1
        }
        if(flag == 1) {
            UserDto userNow = userService.findById(SecurityUtils.getCurrentUserId());
            //查询当前会员角色情况 1林长，2兼职护林员，3专职护林员
            int role = userService.findRoleByUser(userNow);
            users = userService.selUsersByRole(0, nodes.getParentId(), nodes.getId(), role);
        }else{
            users = userService.findByAreaId2(nodes.getId());
        }
        for(User user : users){
            TreeNodes treeNodes = new TreeNodes(user.getId().intValue(),0,1,user.getNickName(),user.getLzzw(),user.getAvatarPath());
            nodes.getChildren().add(treeNodes);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppAreaDto create(AppArea resources) {
        if(null == resources.getFid() || 0 == resources.getFid()){
            throw new BadRequestException("请选择上级责任区");
        }
        if(StringUtils.isEmpty(resources.getTitle())){
            throw new BadRequestException("请填写责任区名称");
        }
        List check = appAreaRepository.findByTitle(resources.getTitle().trim());
        if(check.size()>0){
            throw new BadRequestException("责任区名称重复");
        }
        return appAreaMapper.toDto(appAreaRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(AppArea resources) {
        if(resources.getAreaId() != 1 && (null == resources.getFid() || 0 == resources.getFid()) ){
            throw new BadRequestException("请选择上级责任区");
        }
        if(resources.getAreaId() == 1){
            resources.setFid(0);    //保证是根节点
        }
        AppArea appArea = appAreaRepository.findById(resources.getAreaId()).orElseGet(AppArea::new);
        ValidationUtil.isNull( appArea.getAreaId(),"AppArea","id",resources.getAreaId());

        if(StringUtils.isEmpty(resources.getTitle())){
            throw new BadRequestException("请填写责任区名称");
        }
        if(!resources.getTitle().trim().equals(appArea.getTitle().trim())) {
            List check = appAreaRepository.findByTitle(resources.getTitle().trim());
            if (check.size() > 0) {
                throw new BadRequestException("责任区名称重复");
            }
        }

        appArea.copy(resources);
        appAreaRepository.save(appArea);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer areaId : ids) {
            if (areaId == 1) {
                throw new BadRequestException("抱歉，根节点不能删除");
            }
            appAreaRepository.deleteById(areaId);
        }
    }

    @Override
    public void download(List<AppAreaDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (AppAreaDto appArea : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("名称", appArea.getTitle());
            map.put("父级ID", appArea.getFid());
            map.put("国土总面积", appArea.getGtzmj());
            map.put("林地总面积", appArea.getLdzmj());
            map.put("有林地", appArea.getYld());
            map.put("灌木林地", appArea.getGmld());
            map.put("未成林地", appArea.getWcld());
            map.put("苗圃地", appArea.getMpd());
            map.put("无林木林地", appArea.getWlmld());
            map.put("辅助生产林地", appArea.getFzscld());
            map.put("图片", appArea.getImg());
            map.put("点位JSON", appArea.getPoints());
            map.put("详情", appArea.getContent());
            map.put("状态", appArea.getStatus());
            map.put(" createTime",  appArea.getCreateTime());
            map.put(" updateTime",  appArea.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}